`timescale 1ns/100ps
`default_nettype none

// SRAM base address of pre-IDCT data
`define PRE_IDCT_BASE_ADDR 18'b0
// SRAM base address of YUV data
`define YUV_BASE_ADDR 18'd70144
`define U_BASE_ADDR 18'd108544
`define V_BASE_ADDR 18'd127744

/***********************************************
 * Perform block IDCT for all values in 160x120
 ***********************************************/
module IDCT (
    input logic CLOCK_50_I,             // 50 MHz Clock
    input logic resetn,                 // Reset
    input logic start,               // Start signal
    input logic [15:0] SRAM_Read,         // Data read from SRAM
    
    output logic [15:0] SRAM_Write,         // Data to write to SRAM
    output logic [17:0] SRAM_Addr,        // SRAM address
    output logic SRAM_we,                    // SRAM write enable
    output logic finish              // Finish signal
);

/***********************************
 * Variable declaration
 ***********************************/
// Main states
enum logic [3:0] {
    S0,
    S1,
    S2,
    S3,
    S4,
    S5,
    S6,
    S7,
    S8,
    S9,
    S10
} state;

// Base address offset for pre-IDCT data and YUV data
logic [17:0] preIDCToffset, yuvOffset;
logic [5:0] preIDCTrow, preIDCTcol;
// Indicate if Y pre IDCT read is done
logic preIDCTYDone, preIDCTYDone_buf;
logic [5:0] yuvRow, yuvCol;
// Indicate if Y post IDCT Write is done
logic yDone, yDone_buf;

// Are we going to S3 from S2? or From S6?
logic fromS2;

// Multiplier operates
logic [31:0]    op01, 
                op02, 
                op11, 
                op12, 
                mulResult0, 
                mulResult1; 

// For spLoader0
logic spLoader0_clearResult;
logic [17:0] spLoader0BaseAddr;
logic spLoader0Start;
logic [6:0] spLoader0_dpAddr0;
logic [31:0] spLoader0_dpWrite0;
logic spLoader0_dpwe0;
logic [17:0] spLoader0_SRAMAddr;
logic spLoader0Finish;

// For spLoader1
logic spLoader1_clearResult;
logic [17:0] spLoader1BaseAddr;
logic spLoader1Start;
logic [6:0] spLoader1_dpAddr0;
logic [31:0] spLoader1_dpWrite0;
logic spLoader1_dpwe0;
logic [17:0] spLoader1_SRAMAddr;
logic spLoader1Finish;

// For sWriter0
logic sWriter0_clearResult;
logic [17:0] sWriter0BaseAddr;
logic sWriter0Start;
logic [6:0] sWriter0_dpRAM10_Addr1;
logic [31:0] sWriter0_dpRAM10_Write1;
logic sWriter0_dpRAM10_we1;
logic [17:0] sWriter0_SRAMAddr;
logic [15:0] sWriter0_SRAMWrite;
logic sWriter0_SRAMwe;
logic sWriter0Finish;

// For sWriter1
logic sWriter1_clearResult;
logic [17:0] sWriter1BaseAddr;
logic sWriter1Start;
logic [6:0] sWriter1_dpRAM11_Addr1;
logic [31:0] sWriter1_dpRAM11_Write1;
logic sWriter1_dpRAM11_we1;
logic [17:0] sWriter1_SRAMAddr;
logic [15:0] sWriter1_SRAMWrite;
logic sWriter1_SRAMwe;
logic sWriter1Finish;

// For t Calculator 0
logic tCalc0_clearResult;
logic [6:0] tCalc0_dpRAM00_Addr0, tCalc0_dpRAM00_Addr1;
logic [6:0] tCalc0_dpRAM10_Addr0;
logic [31:0] tCalc0_dpRAM10_Write0;
logic tCalc0_dpRAM10_we0;
logic [31:0] tCalc0_op01, tCalc0_op02;
logic tCalc0Start, tCalc0Finish;

// For t Calculator 1
logic tCalc1_clearResult;
logic [6:0] tCalc1_dpRAM01_Addr0, tCalc1_dpRAM01_Addr1;
logic [6:0] tCalc1_dpRAM11_Addr0;
logic [31:0] tCalc1_dpRAM11_Write0;
logic tCalc1_dpRAM11_we0;
logic [31:0] tCalc1_op11, tCalc1_op12;
logic tCalc1Start, tCalc1Finish;

// For s Calculator 0
logic sCalc0_clearResult;
logic [6:0] sCalc0_dpRAM00_Addr1, sCalc0_dpRAM10_Addr0;
logic [6:0] sCalc0_dpRAM10_Addr1;
logic [31:0] sCalc0_dpRAM10_Write1;
logic sCalc0_dpRAM10_we1;
logic [31:0] sCalc0_op01, sCalc0_op02;
logic sCalc0Start, sCalc0Finish;

// For s Calculator 1
logic sCalc1_clearResult;
logic [6:0] sCalc1_dpRAM01_Addr1, sCalc1_dpRAM11_Addr0;
logic [6:0] sCalc1_dpRAM11_Addr1;
logic [31:0] sCalc1_dpRAM11_Write1;
logic sCalc1_dpRAM11_we1;
logic [31:0] sCalc1_op11, sCalc1_op12;
logic sCalc1Start, sCalc1Finish;

// For Dual Port RAMs
// DP_RAM00
logic [6:0] dpRAM00_Addr0, dpRAM00_Addr1;
logic [31:0] dpRAM00_Write0, dpRAM00_Write1;
logic dpRAM00_we0, dpRAM00_we1;
logic [31:0] dpRAM00_Read0, dpRAM00_Read1;
// DP_RAM10
logic [6:0] dpRAM10_Addr0, dpRAM10_Addr1;
logic [31:0] dpRAM10_Write0, dpRAM10_Write1;
logic dpRAM10_we0, dpRAM10_we1;
logic [31:0] dpRAM10_Read0, dpRAM10_Read1;
// DP_RAM01
logic [6:0] dpRAM01_Addr0, dpRAM01_Addr1;
logic [31:0] dpRAM01_Write0, dpRAM01_Write1;
logic dpRAM01_we0, dpRAM01_we1;
logic [31:0] dpRAM01_Read0, dpRAM01_Read1;
// DP_RAM11
logic [6:0] dpRAM11_Addr0, dpRAM11_Addr1;
logic [31:0] dpRAM11_Write0, dpRAM11_Write1;
logic dpRAM11_we0, dpRAM11_we1;
logic [31:0] dpRAM11_Read0, dpRAM11_Read1;

/************************************
 * Submodule declaration
 ************************************/

// Instantiate 2 multipliers
Mul32 mul0(
    .op1(op01),
    .op2(op02),
    .result(mulResult0)
);
Mul32 mul1(
    .op1(op11),
    .op2(op12),
    .result(mulResult1)
);

// 2 S Prime Loaders
SPLoad spLoader0 (
    .CLOCK_50_I(CLOCK_50_I),
    .resetn(resetn),
    .clearResult(spLoader0_clearResult),
    .preIDCTYDone_in(preIDCTYDone_buf),
    .DP_Read(dpRAM00_Read0),
    .SRAM_Read(SRAM_Read),
    .SRAM_BaseAddr(spLoader0BaseAddr),
    .start(spLoader0Start),
    
    .DP_Addr(spLoader0_dpAddr0),
    .DP_Write(spLoader0_dpWrite0),
    .DP_we(spLoader0_dpwe0),
    .SRAM_Addr(spLoader0_SRAMAddr),
    .finish(spLoader0Finish)
);

SPLoad spLoader1 (
    .CLOCK_50_I(CLOCK_50_I),
    .resetn(resetn),
    .clearResult(spLoader1_clearResult),
    .preIDCTYDone_in(preIDCTYDone_buf),
    .DP_Read(dpRAM01_Read0),
    .SRAM_Read(SRAM_Read),
    .SRAM_BaseAddr(spLoader1BaseAddr),
    .start(spLoader1Start),
    
    .DP_Addr(spLoader1_dpAddr0),
    .DP_Write(spLoader1_dpWrite0),
    .DP_we(spLoader1_dpwe0),
    .SRAM_Addr(spLoader1_SRAMAddr),
    .finish(spLoader1Finish)
);

// 2 S Writers
SWrite sWriter0 (
    .CLOCK_50_I(CLOCK_50_I),
    .resetn(resetn),
    .clearResult(sWriter0_clearResult),
    .yDone_in(yDone_buf),
    .DP_Read(dpRAM10_Read1),
    .SRAM_Read(SRAM_Read),
    .SRAM_BaseAddr(sWriter0BaseAddr),
    .start(sWriter0Start),
    
    .DP_Addr(sWriter0_dpRAM10_Addr1),
    .DP_Write(sWriter0_dpRAM10_Write1),
    .DP_we(sWriter0_dpRAM10_we1),
    .SRAM_Addr(sWriter0_SRAMAddr),
    .SRAM_Write(sWriter0_SRAMWrite),    
    .SRAM_we(sWriter0_SRAMwe),
    .finish(sWriter0Finish)
);

SWrite sWriter1 (
    .CLOCK_50_I(CLOCK_50_I),
    .resetn(resetn),
    .clearResult(sWriter1_clearResult),
    .yDone_in(yDone_buf),
    .DP_Read(dpRAM11_Read1),
    .SRAM_Read(SRAM_Read),
    .SRAM_BaseAddr(sWriter1BaseAddr),
    .start(sWriter1Start),
    
    .DP_Addr(sWriter1_dpRAM11_Addr1),
    .DP_Write(sWriter1_dpRAM11_Write1),
    .DP_we(sWriter1_dpRAM11_we1),
    .SRAM_Addr(sWriter1_SRAMAddr),
    .SRAM_Write(sWriter1_SRAMWrite),    
    .SRAM_we(sWriter1_SRAMwe),
    .finish(sWriter1Finish)
);

// 2 T calculators
TCalc tCalc0 (
    .CLOCK_50_I(CLOCK_50_I),
    .resetn(resetn),
    .clearResult(tCalc0_clearResult),
    .DP0_Addr0(tCalc0_dpRAM00_Addr0),
    .DP0_Addr1(tCalc0_dpRAM00_Addr1),
    .DP0_Read0(dpRAM00_Read0),
    .DP0_Read1(dpRAM00_Read1),
    .DP1_Addr0(tCalc0_dpRAM10_Addr0),
    .DP1_Write0(tCalc0_dpRAM10_Write0),
    .DP1_we0(tCalc0_dpRAM10_we0),
    
    .mulResult(mulResult0),
    .mulOp1(tCalc0_op01),
    .mulOp2(tCalc0_op02),
    .start(tCalc0Start),
    .finish(tCalc0Finish)
);

TCalc tCalc1 (
    .CLOCK_50_I(CLOCK_50_I),
    .resetn(resetn),
    .clearResult(tCalc1_clearResult),
    .DP0_Addr0(tCalc1_dpRAM01_Addr0),
    .DP0_Addr1(tCalc1_dpRAM01_Addr1),
    .DP0_Read0(dpRAM01_Read0),
    .DP0_Read1(dpRAM01_Read1),
    .DP1_Addr0(tCalc1_dpRAM11_Addr0),
    .DP1_Write0(tCalc1_dpRAM11_Write0),
    .DP1_we0(tCalc1_dpRAM11_we0),
    
    .mulResult(mulResult1),
    .mulOp1(tCalc1_op11),
    .mulOp2(tCalc1_op12),
    .start(tCalc1Start),
    .finish(tCalc1Finish)
);

// 2 S calculators
SCalc sCalc0 (
    .CLOCK_50_I(CLOCK_50_I),
    .resetn(resetn),
    .clearResult(sCalc0_clearResult),
    .DP0_Addr1(sCalc0_dpRAM00_Addr1),
    .DP1_Addr0(sCalc0_dpRAM10_Addr0),
    .DP0_Read1(dpRAM00_Read1),
    .DP1_Read0(dpRAM10_Read0),
    .DP1_Addr1(sCalc0_dpRAM10_Addr1),
    .DP1_Write1(sCalc0_dpRAM10_Write1),
    .DP1_we1(sCalc0_dpRAM10_we1),
    .mulResult(mulResult0),
    .mulOp1(sCalc0_op01),
    .mulOp2(sCalc0_op02),
    .start(sCalc0Start),
    .finish(sCalc0Finish)
);

SCalc sCalc1 (
    .CLOCK_50_I(CLOCK_50_I),
    .resetn(resetn),
    .clearResult(sCalc1_clearResult),
    .DP0_Addr1(sCalc1_dpRAM01_Addr1),
    .DP1_Addr0(sCalc1_dpRAM11_Addr0),
    .DP0_Read1(dpRAM01_Read1),
    .DP1_Read0(dpRAM11_Read0),
    .DP1_Addr1(sCalc1_dpRAM11_Addr1),
    .DP1_Write1(sCalc1_dpRAM11_Write1),
    .DP1_we1(sCalc1_dpRAM11_we1),
    .mulResult(mulResult1),
    .mulOp1(sCalc1_op11),
    .mulOp2(sCalc1_op12),
    .start(sCalc1Start),
    .finish(sCalc1Finish)
);

// 2 sets of dual port RAMs
//  2 in each set for S'C and TS
// S'C 0
DP_RAM0 dpRAM00 (
    .address_a(dpRAM00_Addr0),
    .address_b(dpRAM00_Addr1),
    .clock(CLOCK_50_I),
    .data_a(dpRAM00_Write0),
    .data_b(dpRAM00_Write1),
    .wren_a(dpRAM00_we0),
    .wren_b(dpRAM00_we1),
    .q_a(dpRAM00_Read0),
    .q_b(dpRAM00_Read1)
);
// TS 0
DP_RAM1 dpRAM10 (
    .address_a(dpRAM10_Addr0),
    .address_b(dpRAM10_Addr1),
    .clock(CLOCK_50_I),
    .data_a(dpRAM10_Write0),
    .data_b(dpRAM10_Write1),
    .wren_a(dpRAM10_we0),
    .wren_b(dpRAM10_we1),
    .q_a(dpRAM10_Read0),
    .q_b(dpRAM10_Read1)
);
// S'C 1
DP_RAM0 dpRAM01 (
    .address_a(dpRAM01_Addr0),
    .address_b(dpRAM01_Addr1),
    .clock(CLOCK_50_I),
    .data_a(dpRAM01_Write0),
    .data_b(dpRAM01_Write1),
    .wren_a(dpRAM01_we0),
    .wren_b(dpRAM01_we1),
    .q_a(dpRAM01_Read0),
    .q_b(dpRAM01_Read1)
);
// TS 1
DP_RAM1 dpRAM11 (
    .address_a(dpRAM11_Addr0),
    .address_b(dpRAM11_Addr1),
    .clock(CLOCK_50_I),
    .data_a(dpRAM11_Write0),
    .data_b(dpRAM11_Write1),
    .wren_a(dpRAM11_we0),
    .wren_b(dpRAM11_we1),
    .q_a(dpRAM11_Read0),
    .q_b(dpRAM11_Read1)
);

/**********************************************************
 * Start logic
 **********************************************************/
//assign preIDCTYDone = (preIDCTrow>=5'd15 && ~(preIDCTrow==5'd15 && preIDCTcol==5'd0) ) ? 1'b1 : 1'b0;
//assign yDone = (yuvRow>=5'd15 && ~(yuvRow==5'd15 && yuvCol==5'd0) ) ? 1'b1 : 1'b0;
assign preIDCTYDone = (preIDCTrow>=6'd15) ? 1'b1 : 1'b0;
assign yDone = (yuvRow>=6'd15) ? 1'b1 : 1'b0;

always_ff @ (posedge CLOCK_50_I or negedge resetn) begin
    if (resetn==1'b0) begin
        preIDCTYDone_buf <= 1'b0;
        yDone_buf <= 1'b0;

        preIDCTrow <= 6'b0;
        preIDCTcol <= 6'b0;
        preIDCToffset <= 18'b0;
        yuvRow <= 6'b0;
        yuvCol <= 6'b0;
        yuvOffset <= 18'b0;

        fromS2 <= 1'b1;

        spLoader0Start <= 1'b0;
        spLoader0BaseAddr <= `PRE_IDCT_BASE_ADDR + preIDCToffset;
        spLoader1Start <= 1'b0;
        spLoader1BaseAddr <= `PRE_IDCT_BASE_ADDR + preIDCToffset;

        sWriter0Start <= 1'b0;
        sWriter0BaseAddr <= `YUV_BASE_ADDR + yuvOffset;
        sWriter1Start <= 1'b0;
        sWriter1BaseAddr <= `YUV_BASE_ADDR + yuvOffset;

        tCalc0Start <= 1'b0;
        tCalc1Start <= 1'b0;
        sCalc0Start <= 1'b0;
        sCalc1Start <= 1'b0;

        finish <= 1'b0;
        
        state <= S0;
    end else begin
        preIDCTYDone_buf <= preIDCTYDone;
        yDone_buf <= yDone;
        case(state)
        S0: begin
            if (start) begin
                preIDCTrow <= 6'b0;
                preIDCTcol <= 6'b0;
                preIDCToffset <= 18'b0;
                yuvRow <= 6'b0;
                yuvCol <= 6'b0;
                yuvOffset <= 18'b0;

                fromS2 <= 1'b1;

                spLoader0Start <= 1'b0;
                spLoader0BaseAddr <= `PRE_IDCT_BASE_ADDR + preIDCToffset;
                spLoader1Start <= 1'b0;
                spLoader1BaseAddr <= `PRE_IDCT_BASE_ADDR + preIDCToffset;

                sWriter0Start <= 1'b0;
                sWriter0BaseAddr <= `YUV_BASE_ADDR + yuvOffset;
                sWriter1Start <= 1'b0;
                sWriter1BaseAddr <= `YUV_BASE_ADDR + yuvOffset;

                tCalc0Start <= 1'b0;
                tCalc1Start <= 1'b0;
                sCalc0Start <= 1'b0;
                sCalc1Start <= 1'b0;

                finish <= 1'b0;

                // Start spLoader0
                //  hook up all required signals to DP_RAM00 and SRAM in
                //  always_comb.
                spLoader0BaseAddr <= `PRE_IDCT_BASE_ADDR + preIDCToffset;
                spLoader0Start <= 1'b1;

                // Advance preIDCT row, column count, and preIDCToffset
                if (preIDCTcol==6'd19) begin
                    preIDCTrow <= preIDCTrow + 6'd1;
                    if (preIDCTrow == 6'd14) begin
                        // Ugly hack, we want preIDCTcol to start from 10 when row is 15
                        preIDCTcol <= 6'd10;    // U and V pre IDCT colum is half the width of Y
                        preIDCToffset <= preIDCToffset + 18'd1128;
                    end else if (preIDCTYDone == 1'b0) begin
                        preIDCTcol <= 6'b0;     // Normal Y pre IDCT column
                        preIDCToffset <= preIDCToffset + 18'd1128;
                    end else if (preIDCTYDone == 1'b1) begin 
                        preIDCTcol <= 6'd10;    // U and V pre IDCT colum is half the width of Y
                        preIDCToffset <= preIDCToffset + 18'd568;
                    end
                end else begin
                    preIDCTcol <= preIDCTcol + 6'd1;
                    preIDCToffset <= preIDCToffset + 18'd8;
                end

                state <= S1;
            end
        end
        S1: begin
            spLoader0Start <= 1'b0;
            // When spLoader0 finishes running,
            //  start tCalc0 and spLoader1
            if (spLoader0Finish) begin
                // Clear spLoader0 result after used once
                spLoader0_clearResult <= 1'b1;

                // tCalc0 signals hook up in always_comb
                tCalc0Start <= 1'b1;

                // spLoader1 signals hook up in always_comb
                spLoader1BaseAddr <= `PRE_IDCT_BASE_ADDR + preIDCToffset;
                spLoader1Start <= 1'b1;

                // Advance preIDCT row, column count, and preIDCToffset
                if (preIDCTcol==6'd19) begin
                    preIDCTrow <= preIDCTrow + 6'd1;
                    if (preIDCTrow == 6'd14) begin
                        // Ugly hack, we want preIDCTcol to start from 10 when row is 16
                        preIDCTcol <= 6'd10;    // U and V pre IDCT colum is half the width of Y
                        preIDCToffset <= preIDCToffset + 18'd1128;
                    end else if (preIDCTYDone == 1'b0) begin
                        preIDCTcol <= 6'b0;     // Normal Y pre IDCT column
                        preIDCToffset <= preIDCToffset + 18'd1128;
                    end else if (preIDCTYDone == 1'b1) begin 
                        preIDCTcol <= 6'd10;    // U and V pre IDCT colum is half the width of Y
                        preIDCToffset <= preIDCToffset + 18'd568;
                    end
                end else begin
                    preIDCTcol <= preIDCTcol + 6'd1;
                    preIDCToffset <= preIDCToffset + 18'd8;
                end
 
                // Goto next state
                state <= S2;
            end
        end
        S2: begin
            // Unset clear result
            spLoader0_clearResult <= 1'b0;

            tCalc0Start <= 1'b0;
            spLoader1Start <= 1'b0;
            // When tCalc0 and spLoader1 both finishes,
            //  start sCalc0, tCalc1, and spLoader0
            if (tCalc0Finish && spLoader1Finish) begin
                // Clear tCalc0 result after used once
                tCalc0_clearResult <= 1'b1;
                // Clear spLoader1 result after used once
                spLoader1_clearResult <= 1'b1;

                // sCalc0 signals hook up in always_comb
                sCalc0Start <= 1'b1;

                // tCalc1 signals hook up in always_comb
                tCalc1Start <= 1'b1;

                // spLoader0 signals hook up in always_comb
                spLoader0BaseAddr <= `PRE_IDCT_BASE_ADDR + preIDCToffset;
                // Tell always_comb we are coming from S2
                fromS2 <= 1'b1;
                spLoader0Start <= 1'b1;

                // Advance preIDCT row, column count, and preIDCToffset
                if (preIDCTcol==6'd19) begin
                    preIDCTrow <= preIDCTrow + 6'd1;
                    if (preIDCTrow == 6'd14) begin
                        // Ugly hack, we want preIDCTcol to start from 10 when row is 15
                        preIDCTcol <= 6'd10;    // U and V pre IDCT colum is half the width of Y
                        preIDCToffset <= preIDCToffset + 18'd1128;
                    end else if (preIDCTYDone == 1'b0) begin
                        preIDCTcol <= 6'b0;     // Normal Y pre IDCT column
                        preIDCToffset <= preIDCToffset + 18'd1128;
                    end else if (preIDCTYDone == 1'b1) begin 
                        preIDCTcol <= 6'd10;    // U and V pre IDCT colum is half the width of Y
                        preIDCToffset <= preIDCToffset + 18'd568;
                    end
                end else begin
                    preIDCTcol <= preIDCTcol + 6'd1;
                    preIDCToffset <= preIDCToffset + 18'd8;
                end
              
                // Goto next state
                state <= S3;
            end
        end
        S3: begin
            // Unset clear result
            tCalc0_clearResult <= 1'b0;
            // Unset clear result
            spLoader1_clearResult <= 1'b0;
            // Unset clear result when we come from S6
            spLoader0_clearResult <= 1'b0;

            sWriter1Start <= 1'b0;
            sCalc0Start <= 1'b0;
            tCalc1Start <= 1'b0;
            spLoader0Start <= 1'b0;
            // When sCalc0 and tCalc1 finish
            //  start tCalc0, sWriter0, and sCalc1
            // Note we don't check spLoader0 or sWriter0 finish,
            //  as it's much faster than sCalc and tCalc
            if (sCalc0Finish && tCalc1Finish) begin
                // Clear sCalc0 result after used once
                sCalc0_clearResult <= 1'b1;
                // Clear tCalc1 result after used once
                tCalc1_clearResult <= 1'b1;
                // Clear spLoader0 result after used once although we don't
                // explictly check it here
                spLoader0_clearResult <= 1'b1;

                // tCalc0 signals hook up in always_comb
                tCalc0Start <= 1'b1;

                // sCalc1 signals hook up in always_comb
                sCalc1Start <= 1'b1;
                
                // sWriter0 signals hook up in always_comb
                sWriter0BaseAddr <= `YUV_BASE_ADDR + yuvOffset;
                sWriter0Start <= 1'b1;
                
                // Advance yuvOffset, yuvRow, and yuvCol accordingly
                if (yuvCol == 6'd19) begin
                    if (yDone == 1'b0 && yuvRow!=6'd14) begin   // Fugly hack
                        yuvCol <= 6'b0;
                    end else if (yDone == 1'b1 || yuvRow==6'd14) begin // Fugly hack
                        // If Y is Done, U and V is only half of Y's width
                        yuvCol <= 6'd10;    
                    end
                    yuvRow <= yuvRow + 6'd1;
                    if (yuvRow == 6'd14) begin
                        // If Y is done, move on to U
                        yuvOffset <= 18'd38400; //`U_BASE_ADDR - `YUV_BASE_ADDR;
                    end else if (yuvRow == 6'd29) begin
                        // If U is done, move on to V
                        yuvOffset <= 18'd57600; //`V_BASE_ADDR - `YUV_BASE_ADDR;
                    end else begin
                        if (yDone == 1'b0) begin
                            // Advance of yuvOffset for Y
                            yuvOffset <= yuvOffset + 18'd1204;
                        end else if (yDone == 1'b1) begin
                            // U and V yuvOffset advance is different
                            yuvOffset <= yuvOffset + 18'd604;
                        end
                    end
                end else begin
                    yuvCol <= yuvCol + 6'd1;
                    yuvOffset <= yuvOffset + 18'd4;
                end

                // Goto next state
                state <= S4;
            end
        end
        S4: begin
            // Unset clear result
            sCalc0_clearResult <= 1'b0;
            // Unset clear result
            tCalc0Start <= 1'b0;
            // Unset clear result
            spLoader0_clearResult <= 1'b0;

            tCalc0Start <= 1'b0;
            sWriter0Start <= 1'b0;
            sCalc1Start <= 1'b0;
            // When sWriter0 finishes,
            //  start spLoader1
            if (sWriter0Finish) begin
                // Clear sWriter0 result after used once
                sWriter0_clearResult <= 1'b1;

                // spLoader1 signals hook up in always_comb
                spLoader1BaseAddr <= `PRE_IDCT_BASE_ADDR + preIDCToffset;
                spLoader1Start <= 1'b1;

                // Advance preIDCT row, column count, and preIDCToffset
                if (preIDCTcol==6'd19) begin
                    preIDCTrow <= preIDCTrow + 6'd1;
                    if (preIDCTrow == 6'd14) begin
                        // Ugly hack, we want preIDCTcol to start from 10 when row is 15
                        preIDCTcol <= 6'd10;    // U and V pre IDCT colum is half the width of Y
                        preIDCToffset <= preIDCToffset + 18'd1128;
                    end else if (preIDCTYDone == 1'b0) begin
                        preIDCTcol <= 6'b0;     // Normal Y pre IDCT column
                        preIDCToffset <= preIDCToffset + 18'd1128;
                    end else if (preIDCTYDone == 1'b1) begin 
                        preIDCTcol <= 6'd10;    // U and V pre IDCT colum is half the width of Y
                        preIDCToffset <= preIDCToffset + 18'd568;
                    end
                end else begin
                    preIDCTcol <= preIDCTcol + 6'd1;
                    preIDCToffset <= preIDCToffset + 18'd8;
                end
             
                if (yuvRow == 6'd45 && yuvCol == 6'd17) begin
                    // If we are at last few 8x8 blocks,
                    //  go to lead out states.
                    state <= S7;
                end else begin
                    // Goto next state
                    state <= S5;
                end
            end
        end
        S5: begin
            // Unset clear result
            sWriter0_clearResult <= 1'b0;

            spLoader1Start <= 1'b0;
            // When tCalc0 and sCalc1 finish
            //  start sCalc0, spLoader0, and tCalc1
            if (tCalc0Finish && sCalc1Finish) begin
                // Clear tCalc0 result after used once
                tCalc0_clearResult <= 1'b1;
                // Clear sCalc1 result after used once
                sCalc1_clearResult <= 1'b1;
                // Clear spLoader1 result after used once although we don't
                // explictly check it here
                spLoader1_clearResult <= 1'b1;

                // sCalc0 signals hook up in always_comb
                sCalc0Start <= 1'b1;
                
                // tCalc1 signals hook up in always_comb
                tCalc1Start <= 1'b1;

                // spLoader0 signals hook up in always_comb
                spLoader0BaseAddr <= `PRE_IDCT_BASE_ADDR + preIDCToffset;
                spLoader0Start <= 1'b1;

                // Advance preIDCT row, column count, and preIDCToffset
                if (preIDCTcol==6'd19) begin
                    preIDCTrow <= preIDCTrow + 6'd1;
                    if (preIDCTrow == 6'd14) begin
                        // Ugly hack, we want preIDCTcol to start from 10 when row is 15
                        preIDCTcol <= 6'd10;    // U and V pre IDCT colum is half the width of Y
                        preIDCToffset <= preIDCToffset + 18'd1128;
                    end else if (preIDCTYDone == 1'b0) begin
                        preIDCTcol <= 6'b0;     // Normal Y pre IDCT column
                        preIDCToffset <= preIDCToffset + 18'd1128;
                    end else if (preIDCTYDone == 1'b1) begin 
                        preIDCTcol <= 6'd10;    // U and V pre IDCT colum is half the width of Y
                        preIDCToffset <= preIDCToffset + 18'd568;
                    end
                end else begin
                    preIDCTcol <= preIDCTcol + 6'd1;
                    preIDCToffset <= preIDCToffset + 18'd8;
                end

               // Goto next state
                state <= S6;
            end
        end
        S6: begin
            // Unset clear result
            tCalc0_clearResult <= 1'b0;
            // Unset clear result
            sCalc1_clearResult <= 1'b0;
            // Unset clear result
            spLoader1_clearResult <= 1'b0;

            sCalc0Start <= 1'b0;
            spLoader0Start <= 1'b0;
            tCalc0Start <= 1'b0;
            // When spLoader0 finishes,
            //  start sWrite1
            if (spLoader0Finish) begin
                // Clear spLoader0 result after used once
                spLoader0_clearResult <= 1'b1;

                // sWriter1 signals hook up in always_comb
                sWriter1BaseAddr <= `YUV_BASE_ADDR + yuvOffset;
                // Tell always_comb we are not coming from S2
                fromS2 <= 1'b0;
                sWriter1Start <= 1'b1;
               
                // Advance yuvOffset, yuvRow, and yuvCol accordingly
                if (yuvCol == 6'd19) begin
                    if (yDone == 1'b0 && yuvRow!=6'd14) begin   // Fugly hack
                        yuvCol <= 6'b0;
                    end else if (yDone == 1'b1 || yuvRow==6'd14) begin // Fugly hack
                        // If Y is Done, U and V is only half of Y's width
                        yuvCol <= 6'd10;    
                    end
                    yuvRow <= yuvRow + 6'd1;
                    if (yuvRow == 6'd14) begin
                        // If Y is done, move on to U
                        yuvOffset <= 18'd38400; //`U_BASE_ADDR - `YUV_BASE_ADDR;
                    end else if (yuvRow == 6'd29) begin
                        // If U is done, move on to V
                        yuvOffset <= 18'd57600; //`V_BASE_ADDR - `YUV_BASE_ADDR;
                    end else begin
                        if (yDone == 1'b0) begin
                            // Advance of yuvOffset for Y
                            yuvOffset <= yuvOffset + 18'd1204;
                        end else if (yDone == 1'b1) begin
                            // U and V yuvOffset advance is different
                            yuvOffset <= yuvOffset + 18'd604;
                        end
                    end
                end else begin
                    yuvCol <= yuvCol + 6'd1;
                    yuvOffset <= yuvOffset + 18'd4;
                end

                // Go back to S3
                state <= S3;
            end
        end
        S7: begin
            // Unset clear result
            sWriter0_clearResult <= 1'b0;

            spLoader1Start <= 1'b0;
            // When tCalc0 and sCalc1 finishes,
            //  start sCalc0, tCalc1 and sWriter1
            if (tCalc0Finish && sCalc1Finish) begin
                // Clear tCalc0 result after used once
                tCalc0_clearResult <= 1'b1;
                // Clear tCalc1 result after used once
                tCalc1_clearResult <= 1'b1;
                // Clear sWriter0 result after used once although we don't
                // explictly check it here
				sWriter0_clearResult <= 1'b1;
				
                // sCalc0 signals hook up in always_comb
                sCalc0Start <= 1'b1;

                // tCalc1 signals hook up in always_comb
                tCalc1Start <= 1'b1;
               
                // sWriter1 signals hook up in always_comb
                sWriter1BaseAddr <= `YUV_BASE_ADDR + yuvOffset;
                sWriter1Start <= 1'b1;
               
                // Advance yuvOffset, yuvRow, and yuvCol accordingly
                if (yuvCol == 6'd19) begin
                    if (yDone == 1'b0 && yuvRow!=6'd14) begin   // Fugly hack
                        yuvCol <= 6'b0;
                    end else if (yDone == 1'b1 || yuvRow==6'd14) begin // Fugly hack
                        // If Y is Done, U and V is only half of Y's width
                        yuvCol <= 6'd10;    
                    end
                    yuvRow <= yuvRow + 6'd1;
                    if (yuvRow == 6'd14) begin
                        // If Y is done, move on to U
                        yuvOffset <= 18'd38400; //`U_BASE_ADDR - `YUV_BASE_ADDR;
                    end else if (yuvRow == 6'd29) begin
                        // If U is done, move on to V
                        yuvOffset <= 18'd57600; //`V_BASE_ADDR - `YUV_BASE_ADDR;
                    end else begin
                        if (yDone == 1'b0) begin
                            // Advance of yuvOffset for Y
                            yuvOffset <= yuvOffset + 18'd1204;
                        end else if (yDone == 1'b1) begin
                            // U and V yuvOffset advance is different
                            yuvOffset <= yuvOffset + 18'd604;
                        end
                    end
                end else begin
                    yuvCol <= yuvCol + 6'd1;
                    yuvOffset <= yuvOffset + 18'd4;
                end

                // Goto next state
                state <= S8;
            end
        end
        S8: begin
            // Unset clear result
            tCalc0_clearResult <= 1'b0;
            // Unset clear result
            tCalc1_clearResult <= 1'b0;
            // Unset clear result
            sWriter0_clearResult <= 1'b0;

            sCalc0Start <= 1'b0;
            tCalc1Start <= 1'b0;
            sWriter1Start <= 1'b0;
            // When sCalc0 and tClac1 finish,
            //  start sWriter0 and sCalc1
            if (sCalc0Finish && tCalc1Finish) begin
                // Clear sCalc0 result after used once
                sCalc0_clearResult <= 1'b1;
                // Clear tCalc1 result after used once
                tCalc1_clearResult <= 1'b1;
                // Clear sWriter1 result after used once although we don't
                // explictly check it here
				sWriter1_clearResult <= 1'b1;

                // sCalc1 signals hook up in always_comb
                sCalc1Start <= 1'b1;

                // sWriter0 signals hook up in always_comb
                sWriter0BaseAddr <= `YUV_BASE_ADDR + yuvOffset;
                sWriter0Start <= 1'b1;
                
                // Advance yuvOffset, yuvRow, and yuvCol accordingly
                if (yuvCol == 6'd19) begin
                    if (yDone == 1'b0 && yuvRow!=6'd14) begin   // Fugly hack
                        yuvCol <= 6'b0;
                    end else if (yDone == 1'b1 || yuvRow==6'd14) begin // Fugly hack
                        // If Y is Done, U and V is only half of Y's width
                        yuvCol <= 6'd10;    
                    end
                    yuvRow <= yuvRow + 6'd1;
                    if (yuvRow == 6'd14) begin
                        // If Y is done, move on to U
                        yuvOffset <= 18'd38400; //`U_BASE_ADDR - `YUV_BASE_ADDR;
                    end else if (yuvRow == 6'd29) begin
                        // If U is done, move on to V
                        yuvOffset <= 18'd57600; //`V_BASE_ADDR - `YUV_BASE_ADDR;
                    end else begin
                        if (yDone == 1'b0) begin
                            // Advance of yuvOffset for Y
                            yuvOffset <= yuvOffset + 18'd1204;
                        end else if (yDone == 1'b1) begin
                            // U and V yuvOffset advance is different
                            yuvOffset <= yuvOffset + 18'd604;
                        end
                    end
                end else begin
                    yuvCol <= yuvCol + 6'd1;
                    yuvOffset <= yuvOffset + 18'd4;
                end

                state <= S9;
            end
        end
        S9: begin
            // Unset clear result
            sCalc0_clearResult <= 1'b0;
            // Unset clear result
            tCalc1_clearResult <= 1'b0;
            // Unset clear result
            sWriter1_clearResult <= 1'b0;

            sWriter0Start <= 1'b0;
            sCalc1Start <= 1'b0;
            // When sCalc1 finishes,
            //  start sWriter1
            if (sCalc1Finish) begin
                // Clear sCalc1 result after used once
                sCalc1_clearResult <= 1'b1;
                // Clear sWriter0 result after used once although we don't
                // explictly check it here
				sWriter0_clearResult <= 1'b1;

                // sWriter1 signals hook up
                sWriter1BaseAddr <= `YUV_BASE_ADDR + yuvOffset;
                sWriter1Start <= 1'b1;
               
                // Advance yuvOffset, yuvRow, and yuvCol accordingly
                if (yuvCol == 6'd19) begin
                    if (yDone == 1'b0 && yuvRow!=6'd14) begin   // Fugly hack
                        yuvCol <= 6'b0;
                    end else if (yDone == 1'b1 || yuvRow==6'd14) begin // Fugly hack
                        // If Y is Done, U and V is only half of Y's width
                        yuvCol <= 6'd10;    
                    end
                    yuvRow <= yuvRow + 6'd1;
                    if (yuvRow == 6'd14) begin
                        // If Y is done, move on to U
                        yuvOffset <= 18'd38400; //`U_BASE_ADDR - `YUV_BASE_ADDR;
                    end else if (yuvRow == 6'd29) begin
                        // If U is done, move on to V
                        yuvOffset <= 18'd57600; //`V_BASE_ADDR - `YUV_BASE_ADDR;
                    end else begin
                        if (yDone == 1'b0) begin
                            // Advance of yuvOffset for Y
                            yuvOffset <= yuvOffset + 18'd1204;
                        end else if (yDone == 1'b1) begin
                            // U and V yuvOffset advance is different
                            yuvOffset <= yuvOffset + 18'd604;
                        end
                    end
                end else begin
                    yuvCol <= yuvCol + 6'd1;
                    yuvOffset <= yuvOffset + 18'd4;
                end
                state <= S10;
            end
        end
        S10: begin
            // Unset clear result
            sCalc1_clearResult <= 1'b0;
            // Unset clear result
            sWriter0_clearResult <= 1'b0;

            if (sWriter1Finish) begin
                finish <= 1'b1;
                state <= S0;
            end
        end
        default: state <= S0;
        endcase
    end
end

always_comb begin
    if (state==S1) begin
        // Hook up required signals to spLoader0's signal
        dpRAM00_Addr0 = spLoader0_dpAddr0;
        dpRAM00_Write0 = spLoader0_dpWrite0;
        dpRAM00_we0 = spLoader0_dpwe0;
        SRAM_Addr = spLoader0_SRAMAddr;

        // Give default values
        dpRAM00_Addr1 = 7'b0;
        dpRAM00_we1 = 1'b0;
        dpRAM00_Write1 = 32'b0;
        dpRAM01_Addr0 = 7'b0;
        dpRAM01_Addr1 = 7'b0;
        dpRAM01_we0 = 1'b0;
        dpRAM01_we1 = 1'b0;
        dpRAM01_Write0 = 32'b0;
        dpRAM01_Write1 = 32'b0;
        dpRAM10_Addr0 = 7'b0;
        dpRAM10_Addr1 = 7'b0;
        dpRAM10_we0 = 1'b0;
        dpRAM10_we1 = 1'b0;
        dpRAM10_Write0 = 32'b0;
        dpRAM10_Write1 = 32'b0;
        dpRAM11_Addr0 = 7'b0;
        dpRAM11_Addr1 = 7'b0;
        dpRAM11_we0 = 1'b0;
        dpRAM11_we1 = 1'b0;
        dpRAM11_Write0 = 32'b0;
        dpRAM11_Write1 = 32'b0;
        op01 = 32'b0;
        op02 = 32'b0;
        op11 = 32'b0;
        op12 = 32'b0;
        SRAM_we = 1'b0;
        SRAM_Write = 16'b0;

    end else if (state==S2) begin
        // tCalc0 signals hook up
        dpRAM00_Addr0 = tCalc0_dpRAM00_Addr0;
        dpRAM00_Addr1 = tCalc0_dpRAM00_Addr1;
        dpRAM10_Addr0 = tCalc0_dpRAM10_Addr0;
        dpRAM10_Write0 = tCalc0_dpRAM10_Write0;
        dpRAM10_we0 = tCalc0_dpRAM10_we0;
        op01 = tCalc0_op01;
        op02 = tCalc0_op02;
        
        // spLoader1 signals hook up
        dpRAM01_Addr0 = spLoader1_dpAddr0;
        dpRAM01_Write0 = spLoader1_dpWrite0;
        dpRAM01_we0 = spLoader1_dpwe0;
        SRAM_Addr = spLoader1_SRAMAddr;

        // Give default values
        dpRAM00_we0 = 1'b0;
        dpRAM00_we1 = 1'b0;
        dpRAM00_Write0 = 32'b0;
        dpRAM00_Write1 = 32'b0;
        dpRAM01_Addr1 = 7'b0;
        dpRAM01_we1 = 1'b0;
        dpRAM01_Write1 = 32'b0;
        dpRAM10_Addr1 = 7'b0;
        dpRAM10_we1 = 1'b0;
        dpRAM10_Write1 = 32'b0;
        dpRAM11_Addr0 = 7'b0;
        dpRAM11_Addr1 = 7'b0;
        dpRAM11_we0 = 1'b0;
        dpRAM11_we1 = 1'b0;
        dpRAM11_Write0 = 32'b0;
        dpRAM11_Write1 = 32'b0;
        op11 = 32'b0;
        op12 = 32'b0;
        SRAM_we = 1'b0;
        SRAM_Write = 16'b0;
    end else if (state==S3) begin
        // sCalc0 signals hook up
        dpRAM00_Addr1 = sCalc0_dpRAM00_Addr1;
        dpRAM10_Addr0 = sCalc0_dpRAM10_Addr0;
        dpRAM10_Addr1 = sCalc0_dpRAM10_Addr1;
        dpRAM10_Write1 = sCalc0_dpRAM10_Write1;
        dpRAM10_we1 = sCalc0_dpRAM10_we1;
        op01 = sCalc0_op01;
        op02 = sCalc0_op02;

        // tCalc1 signals hook up
        dpRAM01_Addr0 = tCalc1_dpRAM01_Addr0;
        dpRAM01_Addr1 = tCalc1_dpRAM01_Addr1;
        dpRAM11_Addr0 = tCalc1_dpRAM11_Addr0;
        dpRAM11_Write0 = tCalc1_dpRAM11_Write0;
        dpRAM11_we0 = tCalc1_dpRAM11_we0;
        op11 = tCalc1_op11;
        op12 = tCalc1_op12;
        
        if (fromS2==1'b1) begin
            // spLoader0 signals hook up
            dpRAM00_Addr0 = spLoader0_dpAddr0;
            dpRAM00_Write0 = spLoader0_dpWrite0;
            dpRAM00_we0 = spLoader0_dpwe0;
            SRAM_Addr = spLoader0_SRAMAddr;
            
            // Give default values
            dpRAM00_we1 = 1'b0;
            dpRAM00_Write1 = 32'b0;
            dpRAM01_we0 = 1'b0;
            dpRAM01_we1 = 1'b0;
            dpRAM01_Write0 = 32'b0;
            dpRAM01_Write1 = 32'b0;
            dpRAM10_we0 = 1'b0;
            dpRAM10_Write0 = 32'b0;
            dpRAM11_Addr1 = 7'b0;
            dpRAM11_we1 = 1'b0;
            dpRAM11_Write1 = 32'b0;
            SRAM_we = 1'b0;
            SRAM_Write = 16'b0;
        end else begin
            // sWriter1 signals hook up
            dpRAM11_Addr1 = sWriter1_dpRAM11_Addr1;
            dpRAM11_Write1 = sWriter1_dpRAM11_Write1;
            dpRAM11_we1 = sWriter1_dpRAM11_we1;
            SRAM_Addr = sWriter1_SRAMAddr;
            SRAM_Write = sWriter1_SRAMWrite;
            SRAM_we = sWriter1_SRAMwe;
            
            // Give default values
            dpRAM00_Addr0 = 7'b0;
            dpRAM00_we0 = 1'b0;
            dpRAM00_we1 = 1'b0;
            dpRAM00_Write0 = 32'b0;
            dpRAM00_Write1 = 32'b0;
            dpRAM01_we0 = 1'b0;
            dpRAM01_we1 = 1'b0;
            dpRAM01_Write0 = 32'b0;
            dpRAM01_Write1 = 32'b0;
            dpRAM10_we0 = 1'b0;
            dpRAM10_Write0 = 32'b0;
        end
    end else if (state==S4) begin
        // tCalc0 signals hook up
        dpRAM00_Addr0 = tCalc0_dpRAM00_Addr0;
        dpRAM00_Addr1 = tCalc0_dpRAM00_Addr1;
        dpRAM10_Addr0 = tCalc0_dpRAM10_Addr0;
        dpRAM10_Write0 = tCalc0_dpRAM10_Write0;
        dpRAM10_we0 = tCalc0_dpRAM10_we0;
        op01 = tCalc0_op01;
        op02 = tCalc0_op02;

        // sCalc1 signals hook up
        dpRAM01_Addr1 = sCalc1_dpRAM01_Addr1;
        dpRAM11_Addr0 = sCalc1_dpRAM11_Addr0;
        dpRAM11_Addr1 = sCalc1_dpRAM11_Addr1;
        dpRAM11_Write1 = sCalc1_dpRAM11_Write1;
        dpRAM11_we1 = sCalc1_dpRAM11_we1;
        op11 = sCalc1_op11;
        op12 = sCalc1_op12;
        
        // sWriter0 signals hook up
        dpRAM10_Addr1 = sWriter0_dpRAM10_Addr1;
        dpRAM10_Write1 = sWriter0_dpRAM10_Write1;
        dpRAM10_we1 = sWriter0_dpRAM10_we1;
        SRAM_Addr = sWriter0_SRAMAddr;
        SRAM_Write = sWriter0_SRAMWrite;
        SRAM_we = sWriter0_SRAMwe;
        
        // Give default values
        dpRAM00_we0 = 1'b0;
        dpRAM00_we1 = 1'b0;
        dpRAM00_Write0 = 32'b0;
        dpRAM00_Write1 = 32'b0;
        dpRAM01_Addr0 = 7'b0;
        dpRAM01_we0 = 1'b0;
        dpRAM01_we1 = 1'b0;
        dpRAM01_Write0 = 32'b0;
        dpRAM01_Write1 = 32'b0;
        dpRAM11_we0 = 1'b0;
        dpRAM11_Write0 = 32'b0;
    end else if (state==S5) begin
        // tCalc0 signals hook up
        dpRAM00_Addr0 = tCalc0_dpRAM00_Addr0;
        dpRAM00_Addr1 = tCalc0_dpRAM00_Addr1;
        dpRAM10_Addr0 = tCalc0_dpRAM10_Addr0;
        dpRAM10_Write0 = tCalc0_dpRAM10_Write0;
        dpRAM10_we0 = tCalc0_dpRAM10_we0;
        op01 = tCalc0_op01;
        op02 = tCalc0_op02;

        // sCalc1 signals hook up
        dpRAM01_Addr1 = sCalc1_dpRAM01_Addr1;
        dpRAM11_Addr0 = sCalc1_dpRAM11_Addr0;
        dpRAM11_Addr1 = sCalc1_dpRAM11_Addr1;
        dpRAM11_Write1 = sCalc1_dpRAM11_Write1;
        dpRAM11_we1 = sCalc1_dpRAM11_we1;
        op11 = sCalc1_op11;
        op12 = sCalc1_op12;
        
        // spLoader1 signals hook up
        dpRAM01_Addr0 = spLoader1_dpAddr0;
        dpRAM01_Write0 = spLoader1_dpWrite0;
        dpRAM01_we0 = spLoader1_dpwe0;
        SRAM_Addr = spLoader1_SRAMAddr;
        
        // Give default values
        dpRAM00_we0 = 1'b0;
        dpRAM00_we1 = 1'b0;
        dpRAM00_Write0 = 32'b0;
        dpRAM00_Write1 = 32'b0;
        dpRAM01_we1 = 1'b0;
        dpRAM01_Write1 = 32'b0;
        dpRAM10_Addr1 = 7'b0;
        dpRAM10_we1 = 1'b0;
        dpRAM10_Write1 = 32'b0;
        dpRAM11_we0 = 1'b0;
        dpRAM11_Write0 = 32'b0;
        SRAM_we = 1'b0;
        SRAM_Write = 16'b0;
    end else if (state==S6) begin
        // sCalc0 signals hook up
        dpRAM00_Addr1 = sCalc0_dpRAM00_Addr1;
        dpRAM10_Addr0 = sCalc0_dpRAM10_Addr0;
        dpRAM10_Addr1 = sCalc0_dpRAM10_Addr1;
        dpRAM10_Write1 = sCalc0_dpRAM10_Write1;
        dpRAM10_we1 = sCalc0_dpRAM10_we1;
        op01 = sCalc0_op01;
        op02 = sCalc0_op02;

        // tCalc1 signals hook up
        dpRAM01_Addr0 = tCalc1_dpRAM01_Addr0;
        dpRAM01_Addr1 = tCalc1_dpRAM01_Addr1;
        dpRAM11_Addr0 = tCalc1_dpRAM11_Addr0;
        dpRAM11_Write0 = tCalc1_dpRAM11_Write0;
        dpRAM11_we0 = tCalc1_dpRAM11_we0;
        op11 = tCalc1_op11;
        op12 = tCalc1_op12;

        // spLoader0 signals hook up
        dpRAM00_Addr0 = spLoader0_dpAddr0;
        dpRAM00_Write0 = spLoader0_dpWrite0;
        dpRAM00_we0 = spLoader0_dpwe0;
        SRAM_Addr = spLoader0_SRAMAddr;
        
        // Give default values
        dpRAM00_we1 = 1'b0;
        dpRAM00_Write1 = 32'b0;
        dpRAM01_we0 = 1'b0;
        dpRAM01_we1 = 1'b0;
        dpRAM01_Write0 = 32'b0;
        dpRAM01_Write1 = 32'b0;
        dpRAM10_we0 = 1'b0;
        dpRAM10_Write0 = 32'b0;
        dpRAM11_Addr1 = 7'b0;
        dpRAM11_we1 = 1'b0;
        dpRAM11_Write1 = 32'b0;
        SRAM_we = 1'b0;
        SRAM_Write = 16'b0;
    end else if (state==S7) begin
        // tCalc0 signals hook up
        dpRAM00_Addr0 = tCalc0_dpRAM00_Addr0;
        dpRAM00_Addr1 = tCalc0_dpRAM00_Addr1;
        dpRAM10_Addr0 = tCalc0_dpRAM10_Addr0;
        dpRAM10_Write0 = tCalc0_dpRAM10_Write0;
        dpRAM10_we0 = tCalc0_dpRAM10_we0;
        op01 = tCalc0_op01;
        op02 = tCalc0_op02;

        // sCalc1 signals hook up
        dpRAM01_Addr1 = sCalc1_dpRAM01_Addr1;
        dpRAM11_Addr0 = sCalc1_dpRAM11_Addr0;
        dpRAM11_Addr1 = sCalc1_dpRAM11_Addr1;
        dpRAM11_Write1 = sCalc1_dpRAM11_Write1;
        dpRAM11_we1 = sCalc1_dpRAM11_we1;
        op11 = sCalc1_op11;
        op12 = sCalc1_op12;
        
        // spLoader1 signals hook up
        dpRAM01_Addr0 = spLoader1_dpAddr0;
        dpRAM01_Write0 = spLoader1_dpWrite0;
        dpRAM01_we0 = spLoader1_dpwe0;
        SRAM_Addr = spLoader1_SRAMAddr;
        
        // Give default values
        dpRAM00_we0 = 1'b0;
        dpRAM00_we1 = 1'b0;
        dpRAM00_Write0 = 32'b0;
        dpRAM00_Write1 = 32'b0;
        dpRAM01_we1 = 1'b0;
        dpRAM01_Write1 = 32'b0;
        dpRAM10_Addr1 = 7'b0;
        dpRAM10_we1 = 1'b0;
        dpRAM10_Write1 = 32'b0;
        dpRAM11_we0 = 1'b0;
        dpRAM11_Write0 = 32'b0;
        SRAM_we = 1'b0;
        SRAM_Write = 16'b0;
    end else if (state==S8) begin
        // sCalc0 signals hook up
        dpRAM00_Addr1 = sCalc0_dpRAM00_Addr1;
        dpRAM10_Addr0 = sCalc0_dpRAM10_Addr0;
        dpRAM10_Addr1 = sCalc0_dpRAM10_Addr1;
        dpRAM10_Write1 = sCalc0_dpRAM10_Write1;
        dpRAM10_we1 = sCalc0_dpRAM10_we1;
        op01 = sCalc0_op01;
        op02 = sCalc0_op02;

        // tCalc1 signals hook up
        dpRAM01_Addr0 = tCalc1_dpRAM01_Addr0;
        dpRAM01_Addr1 = tCalc1_dpRAM01_Addr1;
        dpRAM11_Addr0 = tCalc1_dpRAM11_Addr0;
        dpRAM11_Write0 = tCalc1_dpRAM11_Write0;
        dpRAM11_we0 = tCalc1_dpRAM11_we0;
        op11 = tCalc1_op11;
        op12 = tCalc1_op12;
                
        // sWriter1 signals hook up
        dpRAM11_Addr1 = sWriter1_dpRAM11_Addr1;
        dpRAM11_Write1 = sWriter1_dpRAM11_Write1;
        dpRAM11_we1 = sWriter1_dpRAM11_we1;
        SRAM_Addr = sWriter1_SRAMAddr;
        SRAM_Write = sWriter1_SRAMWrite;
        SRAM_we = sWriter1_SRAMwe;
        
        // Give default values
        dpRAM00_Addr0 = 7'b0;
        dpRAM00_we0 = 1'b0;
        dpRAM00_we1 = 1'b0;
        dpRAM00_Write0 = 32'b0;
        dpRAM00_Write1 = 32'b0;
        dpRAM01_we0 = 1'b0;
        dpRAM01_we1 = 1'b0;
        dpRAM01_Write0 = 32'b0;
        dpRAM01_Write1 = 32'b0;
        dpRAM10_we0 = 1'b0;
        dpRAM10_Write0 = 32'b0;
    end else if (state==S9) begin
        // sCalc1 signals hook up
        dpRAM01_Addr1 = sCalc1_dpRAM01_Addr1;
        dpRAM11_Addr0 = sCalc1_dpRAM11_Addr0;
        dpRAM11_Addr1 = sCalc1_dpRAM11_Addr1;
        dpRAM11_Write1 = sCalc1_dpRAM11_Write1;
        dpRAM11_we1 = sCalc1_dpRAM11_we1;
        op11 = sCalc1_op11;
        op12 = sCalc1_op12;

        // sWriter0 signals hook up
        dpRAM10_Addr1 = sWriter0_dpRAM10_Addr1;
        dpRAM10_Write1 = sWriter0_dpRAM10_Write1;
        dpRAM10_we1 = sWriter0_dpRAM10_we1;
        SRAM_Addr = sWriter0_SRAMAddr;
        SRAM_Write = sWriter0_SRAMWrite;
        SRAM_we = sWriter0_SRAMwe;
        
        // Give default values
        dpRAM00_Addr0 = 7'b0;
        dpRAM00_Addr1 = 7'b0;
        dpRAM00_we0 = 1'b0;
        dpRAM00_we1 = 1'b0;
        dpRAM00_Write0 = 32'b0;
        dpRAM00_Write1 = 32'b0;
        dpRAM01_Addr0 = 7'b0;
        dpRAM01_we0 = 1'b0;
        dpRAM01_we1 = 1'b0;
        dpRAM01_Write0 = 32'b0;
        dpRAM01_Write1 = 32'b0;
        dpRAM10_Addr0 = 7'b0;
        dpRAM10_we0 = 1'b0;
        dpRAM10_Write0 = 32'b0;
        dpRAM11_we0 = 1'b0;
        dpRAM11_Write0 = 32'b0;
        op01 = 32'b0;
        op02 = 32'b0;
    end else if (state==S10) begin
        // sWriter1 signals hook up
        dpRAM11_Addr1 = sWriter1_dpRAM11_Addr1;
        dpRAM11_Write1 = sWriter1_dpRAM11_Write1;
        dpRAM11_we1 = sWriter1_dpRAM11_we1;
        SRAM_Addr = sWriter1_SRAMAddr;
        SRAM_Write = sWriter1_SRAMWrite;
        SRAM_we = sWriter1_SRAMwe;
        
        // Give default values
        dpRAM00_Addr0 = 7'b0;
        dpRAM00_Addr1 = 7'b0;
        dpRAM00_we0 = 1'b0;
        dpRAM00_we1 = 1'b0;
        dpRAM00_Write0 = 32'b0;
        dpRAM00_Write1 = 32'b0;
        dpRAM01_Addr0 = 7'b0;
        dpRAM01_Addr1 = 7'b0;
        dpRAM01_we0 = 1'b0;
        dpRAM01_we1 = 1'b0;
        dpRAM01_Write0 = 32'b0;
        dpRAM01_Write1 = 32'b0;
        dpRAM10_Addr0 = 7'b0;
        dpRAM10_Addr1 = 7'b0;
        dpRAM10_we0 = 1'b0;
        dpRAM10_we1 = 1'b0;
        dpRAM10_Write0 = 32'b0;
        dpRAM10_Write1 = 32'b0;
        dpRAM11_Addr0 = 7'b0;
        dpRAM11_we0 = 1'b0;
        dpRAM11_Write0 = 32'b0;
        op01 = 32'b0;
        op02 = 32'b0;
        op11 = 32'b0;
        op12 = 32'b0;
    end else begin
        // Give default values
        dpRAM00_Addr0 = 7'b0;
        dpRAM00_Addr1 = 7'b0;
        dpRAM00_we0 = 1'b0;
        dpRAM00_we1 = 1'b0;
        dpRAM00_Write0 = 32'b0;
        dpRAM00_Write1 = 32'b0;
        dpRAM01_Addr0 = 7'b0;
        dpRAM01_Addr1 = 7'b0;
        dpRAM01_we0 = 1'b0;
        dpRAM01_we1 = 1'b0;
        dpRAM01_Write0 = 32'b0;
        dpRAM01_Write1 = 32'b0;
        dpRAM10_Addr0 = 7'b0;
        dpRAM10_Addr1 = 7'b0;
        dpRAM10_we0 = 1'b0;
        dpRAM10_we1 = 1'b0;
        dpRAM10_Write0 = 32'b0;
        dpRAM10_Write1 = 32'b0;
        dpRAM11_Addr0 = 7'b0;
        dpRAM11_Addr1 = 7'b0;
        dpRAM11_we0 = 1'b0;
        dpRAM11_we1 = 1'b0;
        dpRAM11_Write0 = 32'b0;
        dpRAM11_Write1 = 32'b0;
        op01 = 32'b0;
        op02 = 32'b0;
        op11 = 32'b0;
        op12 = 32'b0;
        SRAM_Addr = 18'b0;
        SRAM_we = 1'b0;
        SRAM_Write = 16'b0;
    end
end

endmodule
